///\todo upgrade

//////////////////////////////////////////////////////////////////////////////////
//                                                                              //
//  This file is part of the buola project (https://code.google.com/p/buola/).  //
//                                                                              //
//  Copyright(c) 2007-2012 Xavi Gratal                                          //
//  gratal AT gmail DOT com                                                     //
//                                                                              //
//  Buola is free software: you can redistribute it and/or modify               //
//  it under the terms of the GNU General Public License as published by        //
//  the Free Software Foundation, either version 3 of the License, or           //
//  (at your option) any later version.                                         //
//                                                                              //
//  Buola is distributed in the hope that it will be useful,                    //
//  but WITHOUT ANY WARRANTY; without even the implied warranty of              //
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               //
//  GNU General Public License for more details.                                //
//                                                                              //
//  You should have received a copy of the GNU General Public License           //
//  along with buola.  If not, see <http://www.gnu.org/licenses/>.              //
//                                                                              //
//////////////////////////////////////////////////////////////////////////////////

#ifndef _BUOLA_OS_CAPPMENU_H_
#define _BUOLA_OS_CAPPMENU_H_

#include <buola/io/curi.h>
#include <unordered_map>
#include <set>

namespace buola { namespace os {

///////////////////////////////////////////////////////////////////
/////////////////////// Class CAppMenu ////////////////////////////
///////////////////////////////////////////////////////////////////
//
// This class represents an application, and its abilities to open
// mime types and different actions supported
//
///////////////////////////////////////////////////////////////////

class CAppMenu
{
    struct SRule
    {
        virtual ~SRule();
        virtual bool Check(CApplication*)=0;
        std::string mType;
    };

    struct SFilenameRule : public SRule
    {
        virtual bool Check(CApplication*);
        std::string mFilename;
    };

    struct SCategoryRule : public SRule
    {
        virtual bool Check(CApplication*);
        std::string mCategory;
    };

    struct SBooleanRule : public SRule
    {
        virtual ~SBooleanRule();
        std::vector<SRule*> mSubRules;
    };

    struct SOrRule : public SBooleanRule
    {
        virtual bool Check(CApplication*);
    };

    struct SAndRule : public SBooleanRule
    {
        virtual bool Check(CApplication*);
    };

    struct SNotRule : public SBooleanRule
    {
        virtual bool Check(CApplication*);
    };

public:
    CAppMenu(CAppMenu *pParent);
    CAppMenu(const std::string &pName);

    const std::vector<CAppMenu*> &GetSubMenus()     {   return mSubMenus;   }
    const std::vector<CApplication*> &GetApps()     {   return mApps;       }
    const std::wstring &GetName()                       {   return mName;       }
    const std::wstring &GetComment()                    {   return mComment;    }
    const std::string &GetIcon()                        {   return mIcon;       }
    bool empty();

private:
//internal functions
    SRule *ParseRule(xml::CNode pNode);
    void Parse(xml::CNode pNode);

    void CalcCandidates();
    void Include(std::vector<CApplication*> &pDest,SRule *pRule,bool pUnalloc);
    void CalcTree(bool pPass2);
    io::CURI FindDirectory(const std::string &pDirectory);
    void CalcDirectory();

private:
    io::CURI mURL;

    //parsed info
    CAppMenu *mParent;

    std::vector<CAppMenu*> mSubMenus;
    std::vector<io::CURI> mAppDirs;
    std::vector<io::CURI> mDirectoryDirs;

    std::string mDirectory;
    std::wstring mName;
    std::wstring mComment;
    std::string mIcon;
    bool mOnlyUnallocated;
    bool mDeleted;

    std::vector<SRule*> mRules;

    std::unordered_map<std::string,io::CURI> mPool;
    std::set<CApplication*> mCandidates;
    std::set<CApplication*> mUsedCandidates;
    std::vector<CApplication*> mApps;

    friend CAppMenu *get_app_menu(const std::string &pName);
};

CAppMenu *get_app_menu(const std::string &pName);
CAppMenu *get_default_app_menu();

/*namespace os*/ } /*namespace buola*/ }

#endif
